<?php
/**
 * @copyright: ©2024 永州 微聚商网络科技有限公司
 * @link: https://www.wEijuyunke.com
 */

namespace app\mobile\controller;

use app\admin\model\FigureCompositeSound;
use app\BaseController;
use app\common\service\AgentApiService;
use think\App;
use think\facade\Request;
use think\facade\Db;
use think\facade\Log;
use think\Model;
use app\admin\model\FigureUser;
use app\admin\model\FigureVoiceTwin;
use app\common\service\ApiService;
use app\admin\model\FigureCloneSet;

/**
 * 声音克隆操作
 *
 * @author Administrator
 *
 */
class Voice extends BaseController
{

    /**
     * 随机文案
     * http://aigc.weijuyunke.cn/mobile/voice/randExample
     */
    public function randExample()
    {
        $json_string = file_get_contents(root_path() . "public/json/voice.json");
        $list = json_decode($json_string, true);

        $key = array_rand($list); // 获取随机元素的键名
        $value = $list[$key]['content']; // 获取随机元素的值

        return result(0, 'success', $value);
    }

    /**
     * 声音训练(高保真)
     * http://aigc.weijuyunke.cn/mobile/voice/ttsUpload
     *
     * @param
     *            uid 用户id
     * @param
     *            name 名称
     * @param
     *            sex 性别
     * @param
     *            voice_urls 语音链接
     */
    public function ttsUpload()
    {
        try {
            $uid = input('uid');

            $user = FigureUser::where('id', $uid)->find();
            if (empty($user)) {
                return result(-1, '用户不存在');
            }

            $voice_urls = input('voice_urls');
            if (empty($voice_urls)) {
                return result(-1, 'voice_urls必传');
            }
            $voiceData = array(
                'uid' => $uid,
                'name' => input('name'),
                'sex' => input('sex'),
                'train_mode' => 2,
                'current_status' => 'sent',
                'voice_urls' => json_encode($voice_urls)
            );
            if (!$user['is_member']) {

                if ($user['balance'] < sysconfig('tally', 'voice_high_deduct')) {
                    return result(-2, '点数不足，请充值');
                }
            } else {
                if ($user['voice_twin_count'] < 1 && $user['balance'] < sysconfig('tally', 'voice_high_deduct')) {
                    return result(-2, '次数和点数不足，请充值');
                }
            }
            if (sysconfig('account', 'operation_version') == 2) {
                $apiService = new AgentApiService();
                $result = $apiService->ttsUpload([
                    'name' => input('name'),
                    'sex' => input('sex'),
                    'voice_urls' => $voice_urls
                ]);

                if (isset($result['code']) && $result['code'] != 1) {
                    return result(-1, '失败');
                } else {
                    $voiceData['_id'] = $result['data']['id'];
                }
            }
            // $voices = [];
            // array_push($voices, $voice_urls);
            $userVoice = new FigureVoiceTwin();
            $userVoice->save($voiceData);
            $log_no = getPayNo('VC');
            user_balance_used($uid, $log_no, 2, 30);
            $userVoice->save([
                'log_no' => $log_no,
                'is_status' => 1,
                'current_status' => 'sent'
            ]);

            return result(0, '提交成功，等待审核');
        } catch (\Exception $e) {
            return result(-1, '异常' . $e->getLine() . "--->" . $e->getMessage());
            exit();
        }
    }

    /**
     * 声音继续提交(高保真)
     * http://aigc.weijuyunke.cn/mobile/voice/ttsContinue
     *
     * @param
     *            uid 用户id
     * @param
     *            voice_id 语音id
     * @param
     *            voice_urls 语音链接
     */
    public function ttsContinue()
    {
        try {
            $uid = input('uid');
            $voice_id = input('voice_id');

            $user = FigureUser::where('id', $uid)->find();
            if (empty($user)) {
                return result(-1, '用户不存在');
            }

            $voice = FigureVoiceTwin::where([
                'uid' => $uid,
                'id' => $voice_id
            ])->find();

            if (empty($voice)) {
                return result(-1, '声音不存在');
            }

            $voice_urls = input('voice_urls');
            if (empty($voice_urls)) {
                return result(-1, 'voice_urls必传');
            }

            $voice->save([
                'voice_urls' => json_encode($voice_urls)
            ]);

            if ($voice['is_status'] == 2) {
                if (sysconfig('account', 'operation_version') == 2) {
                    $apiService = new AgentApiService();

                } else {
                    $apiService = new ApiService();

                }
                $result = $apiService->ttsContinue([
                    'id' => $voice['_id'],
                    'voice_urls' => $voice_urls
                ]);

                if (isset($result['code']) && $result['code'] == 1) {

                    $voice->save([
                        'current_status' => 'sent'
                    ]);

                    return result(0, 'success', $result['data']);
                } else {
                    return result(-1, $result['msg']);
                }
            } else {

                if (!$user['is_member']) {

                    if ($user['balance'] < sysconfig('tally', 'voice_high_deduct')) {
                        return result(-2, '点数不足，请充值');
                    }
                } else {
                    if ($user['voice_twin_count'] < 1 && $user['balance'] < sysconfig('tally', 'voice_high_deduct')) {
                        return result(-2, '次数和点数不足，请充值');
                    }
                }

                user_balance_used($uid, $voice['log_no'], 2, 30);

                $voice->save([
                    'is_status' => 1
                ]);

                return result(0, '提交成功，等待审核');
            }
        } catch (\Exception $e) {
            return result(-1, '异常' . $e->getLine() . "--->" . $e->getMessage());
            exit();
        }
    }

    /**
     * 声音合成(高保真)
     * http://aigc.weijuyunke.cn/mobile/voice/ttsVoice
     *
     * @param
     *            uid 用户id
     * @param
     *            text 文本
     * @param
     *            voice_id 语音id
     * @param
     *            speechRate 语速 1是正常速度。这个值越大，语速越快
     */
    public function ttsVoice()
    {
        try {
            $uid = input('uid');
            $voice_id = input('voice_id');

            $user = FigureUser::where('id', $uid)->find();
            if (empty($user)) {
                return result(-1, '用户不存在');
            }

            $text = input('text');
            if (empty($text)) {
                return result(-1, '请输入文本内容');
            }

            $voice = FigureVoiceTwin::where([
                'uid' => $uid,
                'id' => $voice_id
            ])->find();

            if (empty($voice)) {
                return result(-1, '声音不存在');
            }

            if (empty($voice['_id'])) {
                return result(-1, '声音异常');
            }

            $speechRate = empty(input('speechRate')) ? 1 : input('speechRate');

            if (sysconfig('account', 'operation_version') == 2) {
                $apiService = new AgentApiService();

            } else {
                $apiService = new ApiService();

            }
            $result = $apiService->ttsVoice([
                'id' => $voice['_id'],
                'text' => $text,
                'speedRatio' => $speechRate
            ]);

            if (isset($result['code']) && $result['code'] == 1) {
                return result(0, 'success', $result['data']);
            } else {
                return result(-1, $result['msg']);
            }
        } catch (\Exception $e) {
            return result(-1, '异常' . $e->getLine() . "--->" . $e->getMessage());
            exit();
        }
    }

    /**
     * 声音合成(高保真SSML)
     * http://aigc.weijuyunke.cn/mobile/voice/ttsSsml
     *
     * @param
     *            uid 用户id
     * @param
     *            text 文本
     * @param
     *            voice_id 语音id
     * @param
     *            speechRate 语速 1是正常速度。这个值越大，语速越快
     */
    public function ttsSsml()
    {
        try {
            $uid = input('uid');
            $voice_id = input('voice_id');

            $user = FigureUser::where('id', $uid)->find();
            if (empty($user)) {
                return result(-1, '用户不存在');
            }

            $text = input('text');
            if (empty($text)) {
                return result(-1, '文案必传');
            }

            $text = html_entity_decode($text);
            $emojiPattern = '/[\x{1F600}-\x{1F64F}\x{1F300}-\x{1F5FF}\x{1F680}-\x{1F6FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{1F900}-\x{1F9FF}\x{1FA70}-\x{1FAFF}]/u';

            // 使用 preg_match_all 检查字符串中是否有匹配的 emoji
            preg_match_all($emojiPattern, $text, $matches);
            if ( count($matches[0]) > 0){
                return result(-1, '文案有误,请检查');
            }
            $voice = FigureVoiceTwin::where([
                'uid' => $uid,
                'id' => $voice_id
            ])->find();
            if (empty($voice)) {
                return result(-1, '声音不存在');
            }
            if (empty($voice['_id'])) {
                return result(-1, '声音异常');
            }
            $compositeSound  = new FigureCompositeSound();
            $compositeSoundInfo =  $compositeSound->where(['text' => $text,'uid' =>$uid,'voice_id'=> $voice_id,'voice_channel' => 2])->find();
            if ($compositeSoundInfo && $compositeSoundInfo['url']){
                return result(0, 'success', ['id'=>$compositeSoundInfo['id'], 'url'=>$compositeSoundInfo['url']]);
            }
            $speechRate = empty(input('speechRate')) ? 1 : input('speechRate');
            if (sysconfig('account', 'operation_version') == 2) {
                $apiService = new AgentApiService();

            } else {
                $apiService = new ApiService();

            }

      //      $length = ceil(strlen($text) / 300) ;
            $length = ceil(mb_strlen($text,'UTF-8') / 100) ;
            $tally = sysconfig('tally', 'high_fidelity_sound');
            $money = round((float)$length * $tally , 2);


            if (!$user['is_member']) {
                if ($user['balance'] < $money) {
                    return result(-2, '点数不足，请充值');
                }
            } else {
                if ($user['high_fidelity_words_number']   < $length * 100 && $user['balance'] < $money) {
                    return result(-2, '次数和点数不足，请充值');
                }
            }
            $result = $apiService->ttsSsml([
                'id' => $voice['_id'],
                'text' => $text,
                'speedRatio' => $speechRate
            ]);
            if (isset($result['code']) && $result['code'] == 1) {
                $log_no = getPayNo('VS');
                $duration = ceil(getDuration(1, $result['data']['url']));
                $insertData =[
                    'uid' =>$uid,
                    'name'=>  $voice['name'],
                    'url'=>   $result['data']['url'],
                    '_id'=>   $result['data']['id'],
                    'voice_id'=>  $voice_id,
                    'text' => $text,
                    'current_status' =>'completed',
                    'duration' =>$duration,
                    'voice_channel' => 2
                ];
                $compositeSound->save($insertData);
                user_balance_used($uid, $log_no, 2, 14, $length);


                return result(0, 'success', ['id'=>$compositeSound->id, 'url'=>$result['data']['url']]);
            } else {
                return result(-1, $result['msg']);
            }
        } catch (\Exception $e) {
            return result(-1, '异常' . $e->getLine() . "--->" . $e->getMessage());
            exit();
        }
    }

    /**
     * 设置试听
     * http://aigc.weijuyunke.cn/mobile/voice/setDefaultVoice
     *
     * @param
     *            uid 用户id
     * @param
     *            voice_id 语音id
     * @param
     *            media_url 试听链接
     */
    public function setDefaultVoice()
    {
        try {
            $uid = input('uid');
            $voice_id = input('voice_id');

            $user = FigureUser::where('id', $uid)->find();
            if (empty($user)) {
                return result(-1, '用户不存在');
            }

            $voice = FigureVoiceTwin::where([
                'uid' => $uid,
                'id' => $voice_id
            ])->find();

            if (empty($voice)) {
                return result(-1, '声音不存在');
            }

            $voice->save([
                'media_url' => input('media_url')
            ]);

            return result(0, '设置成功');
        } catch (\Exception $e) {
            return result(-1, '异常' . $e->getLine() . "--->" . $e->getMessage());
            exit();
        }
    }

    /**
     * 声音训练(标准版)(克隆)
     * http://aigc.weijuyunke.cn/mobile/voice/training
     *
     * @param
     *            uid 用户id
     * @param
     *            name 名称
     * @param
     *            sex 性别
     * @param
     *            voice_urls 语音链接
     */
    public function training()
    {
        try {
            $uid = input('uid');

            $user = FigureUser::where('id', $uid)->find();
            if (empty($user)) {
                return result(-1, '用户不存在');
            }

            $voice_urls = input('voice_urls');
            if (empty($voice_urls)) {
                return result(-1, 'voice_urls必传');
            }

            if (!$user['is_member']) {
                if ($user['balance'] < sysconfig('tally', 'voice_deduct')) {
                    return result(-2, '点数不足，请充值');
                }
            }

            $log_no = getPayNo('VC');

            $voiceData = array(
                'log_no' => $log_no,
                'uid' => $uid,
                'name' => input('name'),
                'sex' => input('sex'),
                'train_mode' => 1,
                'current_status' => 'sent',
                'voice_urls' => json_encode($voice_urls)
            );

            $set = FigureCloneSet::where("id", 1)->find();

            if (isset($set['voice_check']) && $set['voice_check'] == 1) {

                $userVoice = new FigureVoiceTwin();
                $userVoice->save($voiceData);

                user_balance_used($uid, $log_no, 2, 3);

                $userVoice->save([
                    'is_status' => 1,
                    'current_status' => 'sent'
                ]);

                return result(0, '提交成功，等待审核');
            } else {
                if (sysconfig('account', 'operation_version') == 2) {
                    $apiService = new AgentApiService();

                } else {
                    $apiService = new ApiService();

                }

                $result = $apiService->voiceTraining([
                    'name' => $voiceData['name'],
                    'voice_urls' => $voice_urls
                ]);

                if (isset($result['code']) && $result['code'] == 1) {
                    $userVoice = new FigureVoiceTwin();
                    $userVoice->save($voiceData);
                    user_balance_used($uid, $log_no, 2, 3);

                    $userVoice->save([
                        'log_no' => $log_no,
                        '_id' => $result['data']['id'],
                        'current_status' => $result['data']['current_status']
                    ]);

                    return result(0, '提交成功');
                } else {

                    return result(-1, $result['msg']);
                }
            }
        } catch (\Exception $e) {
            return result(-1, '异常' . $e->getLine() . "--->" . $e->getMessage());
            exit();
        }
    }

    /**
     * 声音列表
     * http://aigc.weijuyunke.cn/mobile/voice/trainList
     *
     * @param
     *            uid 用户id
     * @param
     *            name 名称
     * @param
     *            page 页码
     * @param
     *            psize 每页条数
     */
    public function trainList()
    {
        try {
            $uid = input('uid');

            $user = FigureUser::where('id', $uid)->find();
            if (empty($user)) {
                return result(-1, '用户不存在');
            }

            $pindex = max(1, intval(input('page')));
            $psize = empty(input('psize')) ? 10 : intval(input('psize'));

            $where = " uid = {$uid}  AND current_status !=''";

            if (!empty(input('name'))) {
                $name = input('name');
                $where .= " AND name LIKE '%{$name}%'";
            }

            if (!empty(input('train_mode'))) {
                $train_mode = input('train_mode');
                $where .= " AND train_mode = '{$train_mode}'";
            }

            if (!empty(input('current_status'))) {
                $current_status = input('current_status');

                if ($current_status == 'processing') {
                    $where .= " AND (current_status = 'sent' OR current_status = 'pending' OR current_status = 'processing') ";
                } else {
                    $where .= " AND current_status = '{$current_status}'";
                }
            }
            if (!empty(input('buy_expire'))) {
                $buy_expire = input('buy_expire');

                if ($buy_expire == '2') {
                    $where .= " AND (effective_time = '0' OR effective_time > " . time() . ") ";
                }
            }

            $total = FigureVoiceTwin::where($where)->count();
            if ($total) {
                $list = FigureVoiceTwin::where($where)->order('create_time', 'desc')
                    ->limit(($pindex - 1) * $psize, $psize)
                    ->select();
                foreach ($list as $key => $value) {

                    if ($value['effective_time']) {
                        if ($value['effective_time'] < time()) {
                            $list[$key]['buy_expire'] = '1';
                            $list[$key]['buy_expire_name'] = '已过期';
                        } else {
                            $list[$key]['buy_expire'] = '2';
                            $list[$key]['buy_expire_name'] = '未过期';
                        }

                        $list[$key]['effective_time'] = date('Y-m-d ', $value['effective_time']);
                    } else {
                        $list[$key]['buy_expire'] = '2';
                        $list[$key]['buy_expire_name'] = '永久';
                    }
                    if (!empty($value['voice_urls'])) {
                        $list[$key]['voice_urls'] = json_decode($value['voice_urls'], true);
                    }
                }

            } else {
                $list = array();
            }

            $totalPage = ceil($total / $psize);

            return result(0, 'success', array(
                'list' => $list,
                'total' => $total,
                'pindex' => $pindex,
                'psize' => $psize,
                'totalPage' => $totalPage
            ));
        } catch (\Exception $e) {
            return result(-1, '异常' . $e->getLine() . "--->" . $e->getMessage());
            exit();
        }
    }

    /**
     * 声音删除
     * http://aigc.weijuyunke.cn/mobile/voice/trainDel
     *
     * @param
     *            uid 用户id
     * @param
     *            voice_id 声音id
     */
    public function trainDel()
    {
        try {
            $uid = input('uid');
            $voice_id = input('voice_id');

            $user = FigureUser::where('id', $uid)->find();
            if (empty($user)) {
                return result(-1, '用户不存在');
            }

            $voice = FigureVoiceTwin::where([
                'uid' => $uid,
                'id' => $voice_id
            ])->find();
            if (empty($voice)) {
                return result(-1, '声音不存在');
            }

            $voice->delete();
            return result(0, '删除成功');
        } catch (\Exception $e) {
            return result(-1, '异常' . $e->getLine() . "--->" . $e->getMessage());
            exit();
        }
    }

    public function trainText()
    {
        if (sysconfig('account', 'operation_version') == 2) {
            $apiService = new AgentApiService();
        } else {
            $apiService = new ApiService();
        }
        $result = $apiService->xunfeiTrainText();
        if (isset($result['code']) && $result['code'] == 1) {
            $count = count($result['data']);
           $rand = mt_rand(0,$count-1);
           $data[] = $result['data'][$rand];
            return result(0, 'success', $data);
        } else {
            return result(-1, $result['msg']);
        }
    }

    public function voiceTaskAdd()
    {

      try {
            $uid = input('uid');

            $user = FigureUser::where('id', $uid)->find();
            if (empty($user)) {
                return result(-1, '用户不存在');
            }

            $voice_urls = input('voice_urls');
            if (empty($voice_urls)) {
                return result(-1, 'voice_urls必传');
            }
            if (!$user['is_member']) {
                if ($user['balance'] < sysconfig('tally', 'xunfei_sound_train')) {
                    return result(-2, '点数不足，请充值');
                }
            }else{
                if ($user['xunfei_sound_clone_words_number'] < 1) {
                    if ($user['balance'] < sysconfig('tally', 'xunfei_sound_train')) {
                        return result(-2, '点数不足，请充值');
                    }
                }
            }
            $log_no = getPayNo('VC');
            $voiceData = array(
                'log_no' => $log_no,
                'uid' => $uid,
                'name' => input('name'),
                'sex' => input('sex'),
                'age_group' => input('age_group'),
                'language' => input('language'),
                'train_mode' => 3, // 讯飞
                'current_status' => 'sent',
                'voice_urls' => json_encode($voice_urls),
                'seg_id' => input('seg_id'),
            );
            $set = FigureCloneSet::where("id", 1)->find();

            if (isset($set['xunfei_sound_clone_check']) && $set['xunfei_sound_clone_check'] == 1) {
                $userVoice = new FigureVoiceTwin();
                $userVoice->save($voiceData);
                user_balance_used($uid, $log_no, 2, 15);
                $userVoice->save([
                    'is_status' => 1,
                    'current_status' => 'sent'
                ]);
                return result(0, '提交成功，等待审核',$userVoice);
            } else {
                if (sysconfig('account', 'operation_version') == 2) {
                    $apiService = new AgentApiService();
                } else {
                    $apiService = new ApiService();
                }
                $taskAddData = [
                    'age_group' => input('age_group'),
                    'language' => input('language'),
                    'voice_urls' => $voice_urls,
                    'seg_id' => input('seg_id'),
                    'sex' => input('sex'),
                    'name' => input('name'),
                ];

                $result = $apiService->voiceTaskAdd($taskAddData);

                if (isset($result['code']) && $result['code'] == 1) {
                    $userVoice = new FigureVoiceTwin();
                    $voiceData['_id'] = $result['data']['id'];
                    $voiceData['current_status'] = $result['data']['current_status'];
                    $userVoice->save($voiceData);
                    user_balance_used($uid, $log_no, 2, 15);

                    return result(0, '提交成功',$userVoice);
                } else {
                    return result(-1, $result['msg']);
                }
            }
        } catch (\Exception $e) {
            return result(-1, '异常' . $e->getLine() . "--->" . $e->getMessage());
            exit();
        }
    }


    public function voiceClone()
    {
        try {
            $uid = input('uid');

            $user = FigureUser::where('id', $uid)->find();
            if (empty($user)) {
                return result(-1, '用户不存在');
            }


            $msg = input('msg');
            if (empty($msg)) {
                return result(-1, '请输入文本内容');
            }
      //      $length = ceil(strlen($msg) / 300) ;
            $length = ceil(mb_strlen($msg,'UTF-8') / 100) ;
            $tally = sysconfig('tally', 'xunfei_sound_generate');
            if ($tally > 0) {
                $money = round((float)$length * $tally , 2);
            } else {
                $money = 0;
            }
            $voice_id = input('voice_id');
            $compositeSound  = new FigureCompositeSound();
            $compositeSoundInfo =  $compositeSound->where(['text' => $msg,'uid' =>$uid,'voice_id'=> $voice_id,'voice_channel' => 3])->find();
            if ($compositeSoundInfo && $compositeSoundInfo['url']){

                return result(0, 'success', ['id'=>$compositeSoundInfo['id'], 'url'=>$compositeSoundInfo['url']]);
              //  return result(0, 'success', $compositeSoundInfo['url']);
            }
            if (!$user['is_member']) {
                if ($user['balance'] < $money) {
                    return result(-2, '点数不足，请充值');
                }
            } else {
                if ($user['xunfei_sound_generate_words_number'] < $length * 100 && $user['balance'] < $money) {
                    return result(-2, '次数和点数不足，请充值');
                }
            }


            if (empty($voice_id)) {
                return result(-1, 'voice_id必传');
            }
            $voice = FigureVoiceTwin::where([
                'uid' => $uid,
                'id' => $voice_id
            ])->find();

            if (empty($voice)) {
                return result(-1, 'voice不存在');
            }

            $name = $voice['name'];

            $data = array(
                'msg' => $msg,
                'name' => $name,
                'voice_type' => 2,
                'voice_id' => isset($voice) ? $voice['_id'] : $voice_id
            );
            if (input('speechRate') != '') {
                $data['speechRate'] = input('speechRate');
            }

            if (input('pitchRate') != '') {
                $data['pitchRate'] = input('pitchRate');
            }

            if (sysconfig('account', 'operation_version') == 2) {
                $apiService = new AgentApiService();
            } else {
                $apiService = new ApiService();
            }
            $result = $apiService->voiceClone($data);

            if (isset($result['code']) && $result['code'] == 1) {
                $log_no = getPayNo('XVC');
                user_balance_used($uid, $log_no, 2, 16, $length);
                $sound = new FigureCompositeSound();
                $sound->save([
                    'uid' => $uid,
                    'voice_type' => 2,
                    'voice_id' => $voice_id,
                    'name' => $name,
                    'text' => $msg,
                    'status' => 1,
                    '_id' => $result['data']['id'],
                    'url' => $result['data']['url'],
                    'voice_channel' => 3
                ]);

                return result(0, 'success', ['id'=>$sound->id, 'url'=>$result['data']['url']]);
              //  return result(0, '提交成功', $result['data']['url'] );
            } else {
                return result(-1, $result['msg']);
            }
        } catch (\Exception $e) {
            return result(-1, '异常' . $e->getLine() . "--->" . $e->getMessage());
            exit();
        }
    }
}